﻿namespace _01.MobileDevice
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;

    public class GSM
    {
        private static readonly GSM iPhone4S = new GSM("iPhone 4S", "Apple", 929, "NotMe", new Display(3.5, 25), new Battery(BatteryType.LiIon, 200, 8));

        private string model;
        private string manufacturer;
        private decimal? price;
        private string owner;

        public GSM(string model, string manufacturer)
        {
            this.Model = model;
            this.Manufacturer = manufacturer;
            this.CallHistory = new List<Call>();
        }

        public GSM(string model, string manufacturer, decimal? price, string owner)
            : this(model, manufacturer)
        {
            this.Price = price;
            this.Owner = owner;
        }

        public GSM(string model, string manufacturer, decimal? price, string owner, Display display, Battery battery)
            : this(model, manufacturer, price, owner)
        {
            this.Display = display;
            this.Battery = battery;
        }

        public static GSM IPhone4S
        {
            get
            {
                return iPhone4S;
            }
        }

        public List<Call> CallHistory { get; private set; }

        public string Model
        {
            get
            {
                return this.model;
            }

            set
            {
                if (string.IsNullOrEmpty(value))
                {
                    throw new ArgumentException("The model must be not null or empty.");
                }

                this.model = value;
            }
        }

        public string Manufacturer
        {
            get
            {
                return this.manufacturer;
            }

            set
            {
                if (string.IsNullOrEmpty(value))
                {
                    throw new ArgumentException("The manufacturer must be not null or empty.");
                }

                this.manufacturer = value;
            }
        }

        public decimal? Price
        {
            get
            {
                return this.price;
            }

            set
            {
                if (value < 0)
                {
                    throw new ArgumentOutOfRangeException("The price must be positive.");
                }

                this.price = value;
            }
        }

        public string Owner
        {
            get
            {
                return this.owner;
            }

            set
            {
                if (this.owner == string.Empty)
                {
                    throw new ArgumentException();
                }

                this.owner = value;
            }
        }

        public Display Display { get; set; }

        public Battery Battery { get; set; }

        public void AddCall(Call call)
        {
            if (!this.CallHistory.Exists(item => item.GetHashCode() == call.GetHashCode()))
            {
                this.CallHistory.Add(call);
            }
        }

        public void DeleteCall(Call call)
        {
            if (this.CallHistory.Exists(item => item.GetHashCode() == call.GetHashCode()))
            {
                this.CallHistory.Remove(call);
            }
        }

        public void DeleteLongestCall()
        {
            TimeSpan longestDuration = this.CallHistory.Max(call => call.Duration);
            this.CallHistory.RemoveAll(call => call.Duration == longestDuration);
        }

        public void ClearCallHistory()
        {
            if (this.CallHistory.Count > 0)
            {
                this.CallHistory.Clear();
            }
        }

        public decimal CalculateTotalCallsPrice(decimal pricePerMinute)
        {
            return Math.Round(this.CallHistory.Sum(call => (decimal)call.Duration.TotalMinutes * pricePerMinute), 2);
        }

        public string GetCallHistory()
        {
            StringBuilder callHistoryResult = new StringBuilder();

            foreach (var call in this.CallHistory)
            {
                callHistoryResult.AppendLine(call.ToString());
            }

            return callHistoryResult.ToString();
        }

        public override string ToString()
        {
            StringBuilder info = new StringBuilder();
            info.AppendLine("Model: " + this.model);
            info.AppendLine("Manufacturer: " + this.manufacturer);

            if (this.price != null)
            {
                info.AppendLine(string.Format("Price: {0:c}", this.price));
            }

            if (this.owner != null)
            {
                info.AppendLine("Owner: " + this.owner);
            }

            if (this.Battery != null)
            {
                info.AppendLine("Battery - " + this.Battery);
            }

            if (this.Display != null)
            {
                info.AppendLine("Display - " + this.Display);
            }

            return info.ToString();
        }
    }
}
